home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / progjrn / pj_5_3.arc / PJ3.ASM
Assembly Source File  |  1987-10-12  |  5KB  |  222 lines

  1. ; Program to illustrate operation of data rotate and bit mask
  2. ;  features of Graphics Data Controller.  Draws 8x8 character at
  3. ;  specified location, using EGA's 8x8 ROM font.  Designed
  4. ;  for use with modes 0Dh, 0Eh, 0Fh, and 10h.
  5. ; Assembled with MASM 4.0, linked with LINK 3.51.
  6. ; Copyright by Michael Abrash, 2/8/87.
  7. ;
  8. stack    segment    para stack 'STACK'
  9.     db    512 dup(?)
  10. stack    ends
  11. ;
  12. EGA_VIDEO_SEGMENT    equ    0a000h    ;EGA display memory segment
  13. SCREEN_WIDTH_IN_BYTES    equ    044ah    ;offset of BIOS variable
  14. FONT_CHARACTER_SIZE    equ    8    ;# bytes in each font char
  15. ;
  16. ; EGA register equates.
  17. ;
  18. GDC_INDEX    equ    3ceh    ;GDC index register
  19. GDC_ROTATE    equ    3    ;GDC data rotate/logical function
  20.                 ; register index
  21. GDC_BIT_MASK    equ    8    ;GDC bit mask register index
  22. ;
  23. dseg    segment    para common 'DATA'
  24. TEST_TEXT_ROW    equ    69    ;row to display test text at
  25. TEST_TEXT_COL    equ    17    ;column to display test text at
  26. TEST_TEXT_WIDTH    equ    8    ;width of a character in pixels
  27. TestString    label    byte
  28.     db    'Hello, world!',0    ;test string to print.
  29. FontPointer    dd    ?        ;font offset
  30. dseg    ends
  31. ;
  32. ; Macro to set indexed register INDEX of GDC chip to SETTING.
  33. ;
  34. SETGDC    macro    INDEX, SETTING
  35.     mov    dx,GDC_INDEX
  36.     mov    ax,(SETTING SHL 8) OR INDEX
  37.     out    dx,ax
  38.     endm
  39. ;
  40. cseg    segment    para public 'CODE'
  41.     assume    cs:cseg, ds:dseg
  42. start    proc    near
  43.     mov    ax,dseg
  44.     mov    ds,ax
  45. ;
  46. ; Select 640x350 graphics mode.
  47. ;
  48.     mov    ax,010h
  49.     int    10h
  50. ;
  51. ; Set driver to use the 8x8 font.
  52. ;
  53.     mov    ah,11h    ;EGA BIOS character generator function,
  54.     mov    al,30h    ; return info subfunction
  55.     mov    bh,3    ;get 8x8 font pointer
  56.     int    10h
  57.     call    SelectFont
  58. ;
  59. ; Print the test string.
  60. ;
  61.     mov    si,offset TestString
  62.     mov    bx,TEST_TEXT_ROW
  63.     mov    cx,TEST_TEXT_COL
  64. StringOutLoop:
  65.     lodsb
  66.     and    al,al
  67.     jz    StringOutDone
  68.     call    DrawChar
  69.     add    cx,TEST_TEXT_WIDTH
  70.     jmp    StringOutLoop
  71. StringOutDone:
  72. ;
  73. ; Reset the data rotate and bit mask registers.
  74. ;
  75.     SETGDC    GDC_ROTATE, 0
  76.     SETGDC    GDC_BIT_MASK, 0ffh
  77. ;
  78. ; Exit to DOS.
  79. ;
  80.     mov    ah,4ch
  81.     int    21h
  82. Start    endp
  83. ;
  84. ; Subroutine to draw a text character in a linear graphics mode
  85. ;  (0Dh, 0Eh, 0Fh, 010h).
  86. ; Font used should be pointed to by FontPointer.
  87. ;
  88. ; Input:
  89. ;  AL = character to draw
  90. ;  BX = row to draw text character at
  91. ;  CX = column to draw text character at
  92. ;
  93. ;  Forces ALU function to "move".
  94. ;
  95. DrawChar    proc    near
  96.     push    ax
  97.     push    bx
  98.     push    cx
  99.     push    dx
  100.     push    si
  101.     push    di
  102.     push    bp
  103.     push    ds
  104. ;
  105. ; Set DS:SI to point to font and ES to point to display memory.
  106. ;
  107.     lds    si,[FontPointer]    ;point to font
  108.     mov    dx,EGA_VIDEO_SEGMENT
  109.     mov    es,dx            ;point to display memory
  110. ;
  111. ; Calculate screen address of byte character starts in.
  112. ;
  113.     push    ds    ;point to BIOS data segment
  114.     sub    dx,dx
  115.     mov    ds,dx
  116.     xchg    ax,bx
  117.     mov    di,ds:[SCREEN_WIDTH_IN_BYTES]    ;retrieve BIOS
  118.                         ; screen width
  119.     pop    ds
  120.     mul    di    ;calculate offset of start of row
  121.     push    di    ;set aside screen width
  122.     mov    di,cx    ;set aside the column
  123.     and    cl,0111b ;keep only the column in-byte address
  124.     shr    di,1
  125.     shr    di,1
  126.     shr    di,1    ;divide column by 8 to make a byte address
  127.     add    di,ax    ;and point to byte
  128. ;
  129. ; Calculate font address of character.
  130. ;
  131.     sub    bh,bh
  132.     shl    bx,1    ;assumes 8 bytes per character; use
  133.     shl    bx,1    ; a multiply otherwise
  134.     shl    bx,1    ;offset in font of character
  135.     add    si,bx    ;offset in font segment of character
  136. ;
  137. ; Set up the GDC rotation.
  138. ;
  139.     mov    dx,GDC_INDEX
  140.     mov    al,GDC_ROTATE
  141.     mov    ah,cl
  142.     out    dx,ax
  143. ;
  144. ; Set up BH as bit mask for left half,
  145. ; BL as rotation for right half.
  146. ;
  147.     mov    bx,0ffffh
  148.     shr    bh,cl
  149.     neg    cl
  150.     add    cl,8
  151.     shl    bl,cl
  152. ;
  153. ; Draw the character, left half first, then right half in the
  154. ; succeeding byte, using the data rotation to position the character
  155. ; across the byte boundary and then using the bit mask to get the
  156. ; proper portion of the character into each byte.
  157. ; Does not check for case where character is byte-aligned and
  158. ; no rotation and only one write is required.
  159. ;
  160.     mov    bp,FONT_CHARACTER_SIZE
  161.     mov    dx,GDC_INDEX
  162.     pop    cx    ;get back screen width
  163.     dec    cx
  164.     dec    cx    ; -2 because do two bytes for each char
  165. CharacterLoop:
  166. ;
  167. ; Set the bit mask for the left half of the character.
  168. ;
  169.     mov    al,GDC_BIT_MASK
  170.     mov    ah,bh
  171.     out    dx,ax
  172. ;
  173. ; Get the next character byte & write it to display memory.
  174. ; (Left half of character.)
  175. ;
  176.     mov    al,[si]        ;get character byte
  177.     mov    ah,es:[di]    ;load latches
  178.     stosb            ;write character byte
  179. ;
  180. ; Set the bit mask for the right half of the character.
  181. ;
  182.     mov    al,GDC_BIT_MASK
  183.     mov    ah,bl
  184.     out    dx,ax
  185. ;
  186. ; Get the character byte again & write it to display memory.
  187. ; (Right half of character.)
  188. ;
  189.     lodsb            ;get character byte
  190.     mov    ah,es:[di]    ;load latches
  191.     stosb            ;write character byte
  192. ;
  193. ; Point to next line of character in display memory.
  194. ;
  195.     add    di,cx
  196. ;
  197.     dec    bp
  198.     jnz    CharacterLoop
  199. ;
  200.     pop    ds
  201.     pop    bp
  202.     pop    di
  203.     pop    si
  204.     pop    dx
  205.     pop    cx
  206.     pop    bx
  207.     pop    ax
  208.     ret
  209. DrawChar    endp
  210. ;
  211. ; Set the pointer to the font to draw from to ES:BP.
  212. ;
  213. SelectFont    proc    near
  214.     mov    word ptr [FontPointer],bp    ;save pointer
  215.     mov    word ptr [FontPointer+2],es
  216.     ret
  217. SelectFont    endp
  218. ;  
  219. cseg    ends
  220.     end    start
  221.  
  222.